#ifndef __WS_PRIVATE_H__
#define __WS_PRIVATE_H__
#include <iostream>
#include <string_view>
#include <string>
extern "C" struct lws;

namespace sdk {
namespace msg {
  
enum class EJsonMsgName {
    InquireSoftwareInfo,
    StartCapture,
    StartCaptureSucceeded,
    StartCaptureFailed,
    StartCaptureFinished,
    StartTakePicture,
    StartTakePictureFinished,
    StartTakePictureSucceeded,
    ReportTookPicture,
    StartTakePictureFinishedSucceeded,
    StartTakePictureFailed,
    StartTakePictureFinishedFailed,
    Reset,
    SetThresholds,
    SetVideoLightDuty,
    ReportInitialPressure,
    ReporWristPumpStatus,
    ReporPulsePumpStatus,
    ReportCaptureState,
    ReportPulseResult,
    SystemException,
    SystemMemException,
    UpdateFirmware,
};

enum class EJsonMsgNamesp {
    System,
    VisualTracker,
    PulseGenerator,
    BloodGenerator
};

struct WsUserSession;
struct ModulesProxy;

struct MessageHead {
    std::string msgId;
    std::string name;
    std::string nameSpace;
};

struct WsSession {
    WsUserSession *priv;
    lws *wsi;
};

//struct LOG {
//    static const std::string TAG;
//};

inline std::string NameToString(EJsonMsgName name) {
    switch (name) {
        case EJsonMsgName::InquireSoftwareInfo:
            return "InquireSoftwareInfo";
        case EJsonMsgName::StartCapture:
            return "StartCapture";
        case EJsonMsgName::StartCaptureSucceeded:
            return "StartCaptureSucceeded";
        case EJsonMsgName::StartCaptureFailed:
            return "StartCaptureFailed";
        case EJsonMsgName::StartCaptureFinished:
            return "StartCaptureFinished";
        case EJsonMsgName::StartTakePicture:
            return "StartTakePicture";
        case EJsonMsgName::StartTakePictureFinished:
            return "StartTakePictureFinished";
        case EJsonMsgName::StartTakePictureSucceeded:
            return "StartTakePictureSucceeded";
        case EJsonMsgName::ReportTookPicture:
            return "ReportTookPicture";
        case EJsonMsgName::StartTakePictureFinishedSucceeded:
            return "StartTakePictureFinishedSucceeded";
        case EJsonMsgName::StartTakePictureFailed:
            return "StartTakePictureFailed";
        case EJsonMsgName::StartTakePictureFinishedFailed:
            return "StartTakePictureFinishedFailed"; 
        case EJsonMsgName::Reset:
            return "Reset";
        case EJsonMsgName::SetThresholds:
            return "SetThresholds";
        case EJsonMsgName::SetVideoLightDuty:
            return "SetVideoLightDuty";
        case EJsonMsgName::ReportInitialPressure:
            return "ReportInitialPressure";
        case EJsonMsgName::ReporWristPumpStatus:
            return "ReporWristPumpStatus";
        case EJsonMsgName::ReporPulsePumpStatus:
            return "ReporPulsePumpStatus";
        case EJsonMsgName::ReportCaptureState:
            return "ReportCaptureState";
        case EJsonMsgName::ReportPulseResult:
            return "ReportPulseResult";
        case EJsonMsgName::SystemException:
            return "SystemException";
        case EJsonMsgName::SystemMemException:
            return "SystemMemException";
        case EJsonMsgName::UpdateFirmware:
            return "UpdateFirmware";           
    }
    return "unknown namespace";
}  


/**
 * Write a @c KeyType value to an @c ostream.
 *
 * @param stream The stream to write the value to.
 * @param state The @c EJsonMsgName value to write to the @c ostream as a string.
 * @return The @c ostream that was passed in and written to.
 */
inline std::ostream& operator<<(std::ostream& stream, const EJsonMsgName& name) {
    return stream << NameToString(name);
}

/**
 * Write a @c KeyType value to an @c ostream.
 *
 * @param stream The stream to write the value to.
 * @param state The @c EJsonMsgNamesp value to write to the @c ostream as a string.
 * @return The @c ostream that was passed in and written to.
 */
inline std::ostream& operator<<(std::ostream& stream, const EJsonMsgNamesp& namesp) {
    switch(namesp) {
      case EJsonMsgNamesp::System:
        return stream << "System";
      case EJsonMsgNamesp::VisualTracker:
        return stream << "VisualTracker";
      case EJsonMsgNamesp::PulseGenerator:
        return stream << "PulseGenerator";
      case EJsonMsgNamesp::BloodGenerator:
        return stream << "BloodGenerator";
    }
    
    return stream << "Unknow namespace";
}


} // namespace msg
} // namespace sdk
#endif // ! __WS_PRIVATE_H__
